use crate::error::{AsyncOperation, OperationStatus, ProgressReport};
use dashmap::DashMap;
use std::sync::Arc;
use tokio::sync::broadcast;

/// 进度管理服务
#[derive(Debug, Clone)]
pub struct ProgressManager {
    operations: Arc<DashMap<String, AsyncOperation>>,
    progress_sender: broadcast::Sender<ProgressReport>,
}

impl ProgressManager {
    pub fn new() -> Self {
        let (progress_sender, _) = broadcast::channel(1000);
        
        Self {
            operations: Arc::new(DashMap::new()),
            progress_sender,
        }
    }
    
    /// 创建新的异步操作
    pub fn create_operation(&self, operation_type: String) -> String {
        let operation = AsyncOperation::new(operation_type);
        let id = operation.id.clone();
        self.operations.insert(id.clone(), operation);
        id
    }
    
    /// 更新操作进度
    pub fn update_progress(&self, operation_id: &str, current: u64, total: u64, message: String) -> Result<(), String> {
        if let Some(mut operation) = self.operations.get_mut(operation_id) {
            let progress = ProgressReport::new(operation_id.to_string(), current, total, message);
            
            // 发送进度更新
            let _ = self.progress_sender.send(progress.clone());
            
            operation.update_progress(progress);
            Ok(())
        } else {
            Err(format!("Operation {} not found", operation_id))
        }
    }
    
    /// 完成操作
    pub fn complete_operation(&self, operation_id: &str, result: serde_json::Value) -> Result<(), String> {
        if let Some(mut operation) = self.operations.get_mut(operation_id) {
            operation.complete(result);
            Ok(())
        } else {
            Err(format!("Operation {} not found", operation_id))
        }
    }
    
    /// 操作失败
    pub fn fail_operation(&self, operation_id: &str, error: String) -> Result<(), String> {
        if let Some(mut operation) = self.operations.get_mut(operation_id) {
            operation.fail(error);
            Ok(())
        } else {
            Err(format!("Operation {} not found", operation_id))
        }
    }
    
    /// 获取操作状态
    pub fn get_operation(&self, operation_id: &str) -> Option<AsyncOperation> {
        self.operations.get(operation_id).map(|op| op.clone())
    }
    
    /// 获取所有操作
    pub fn get_all_operations(&self) -> Vec<AsyncOperation> {
        self.operations.iter().map(|entry| entry.value().clone()).collect()
    }
    
    /// 清理已完成的操作
    pub fn cleanup_completed(&self) {
        self.operations.retain(|_, operation| {
            !matches!(operation.status, OperationStatus::Completed | OperationStatus::Failed)
        });
    }
    
    /// 订阅进度更新
    pub fn subscribe_progress(&self) -> broadcast::Receiver<ProgressReport> {
        self.progress_sender.subscribe()
    }
    
    /// 取消操作
    pub fn cancel_operation(&self, operation_id: &str) -> Result<(), String> {
        if let Some(mut operation) = self.operations.get_mut(operation_id) {
            operation.status = OperationStatus::Cancelled;
            operation.updated_at = chrono::Utc::now();
            Ok(())
        } else {
            Err(format!("Operation {} not found", operation_id))
        }
    }
}

impl Default for ProgressManager {
    fn default() -> Self {
        Self::new()
    }
}

// 全局进度管理器实例
lazy_static::lazy_static! {
    pub static ref PROGRESS_MANAGER: ProgressManager = ProgressManager::new();
}

/// 进度报告宏
#[macro_export]
macro_rules! report_progress {
    ($operation_id:expr, $current:expr, $total:expr, $message:expr) => {
        if let Err(e) = crate::services::progress::PROGRESS_MANAGER.update_progress(
            $operation_id,
            $current,
            $total,
            $message.to_string(),
        ) {
            log::warn!("Failed to report progress: {}", e);
        }
    };
}

/// 完成操作宏
#[macro_export]
macro_rules! complete_operation {
    ($operation_id:expr, $result:expr) => {
        if let Err(e) = crate::services::progress::PROGRESS_MANAGER.complete_operation(
            $operation_id,
            serde_json::to_value($result).unwrap_or(serde_json::Value::Null),
        ) {
            log::warn!("Failed to complete operation: {}", e);
        }
    };
}

/// 操作失败宏
#[macro_export]
macro_rules! fail_operation {
    ($operation_id:expr, $error:expr) => {
        if let Err(e) = crate::services::progress::PROGRESS_MANAGER.fail_operation(
            $operation_id,
            $error.to_string(),
        ) {
            log::warn!("Failed to mark operation as failed: {}", e);
        }
    };
}
